<template>
  <div v-if="!isMobile" class="div-ctn" @mouseup="onMouseUp($event)">
    <div id="leftDiv" class="left">
      <!--<a href="https://www.shiyinren.com/server/1/221822646.mp3" download="可能222.mp3">点击下载</a>
      <button @click="testaaa">下载CSV</button>-->
      <el-container class="project">
        <img src="./assets/音叶/音叶-logo.png" style="width: 56px;height: 39px;margin-top: 10px;margin-left: 29px;"></img>
      </el-container>

      <el-scrollbar ref="inputScroll" id="scrollId2" class="scrollbar2" :style="'height:' + inputHeight + 'px'" :always="true">
        <el-container class="input-ctn" :style="'height:'+(inputCtnHeight+6)+'px'" v-for="(item, index) in inputList" :key="item" @mouseover="onInputOver($event, index)" @mouseout="onInputOut($event, index)">
            <img src="./assets/音叶/箭头-左.png" style="width: 19px;height: 32px;margin-top: 20px;margin-left: 2px;" v-if="item.select"></img>
            <div class="input-ctn2" :style="'height:'+inputCtnHeight+'px'">
              <el-input v-model="item.value" type="textarea" class="borderless" :input-style="inputStyle"  @focus="onFocus($event, index)" @input="onInput($event, index)" placeholder="请输入文本内容" />
              
              <div v-if="isTranslate" class="jap-ctn">
                <div class="jap-line"></div>
                <el-input v-model="item.japStr" type="textarea" class="borderless" :input-style="inputStyle2" :disabled="true" />
              </div>
              <div style="position: absolute;right: 20px;bottom:0px;" v-if="item.over">
                <!--<el-button @click="onDelete($event, index)">Delete Item</el-button>-->
                <img src="./assets/音叶/icon-删除文本.png" class="item-icon"  @click="onDelete($event, index)"></img>
                <img src="./assets/音叶/icon-保存文本及语音.png" class="item-icon" @click="onInputSave($event, index)"></img>
                <img src="./assets/音叶/icon-点击试听此条文本语音.png" class="item-icon"  @click="onInputPlay($event, index)"></img>
              </div>
              <div class="input-tag">文本{{ index+1 }}</div>
            </div>
        </el-container>
      </el-scrollbar>
      <StateButton class="btn-add" :imgSrc="baseUrl + '/assets/音叶/按钮-添加新文本.png'"  @click="add($event, 'param test')"></StateButton>

      <div class="set-ctn2" v-if="!showSet">
        <img src="./assets/音叶/箭头-下.png" style="width: 32px;height: 19px; margin-left: 50%;margin-top:8px;transform: rotate(180deg)" @click="onShowSet"></img>
      </div>
      <div class="set-ctn" :style="'height:'+setHeight+'px'" v-if="showSet">
        <div class="set-text" style="position:relative;margin-left: 32px;margin-top:5px;">抑扬顿挫</div>
        <img src="./assets/音叶/箭头-下.png" style="position:absolute;width: 32px;height: 19px; left: 50%;top:7px;" @click="onHideSet"></img>
        <div class="yydc"></div>
        <div class="set-text" style="margin-left: 32px;margin-top:5px;position:relative;">音调</div>
        <div class="yydc" :style="'height:'+emoHeight+'px'"></div>

        <el-scrollbar ref="myScroll" id="scrollId" class="scrollbar" :style="'height:'+scrollHeight+'px'" :always="true" height="560px">
          <!--曲线，抑扬顿挫-->
          <div style="position: relative;width: 100%">
            <div style="position:absolute;display: flex;flex-direction: column;top: 20px;">
              <img src="./assets/音叶/旋钮11.png" class="icon-yydc"></img>
              <img src="./assets/音叶/旋钮10.png" class="icon-yydc"></img>
              <img src="./assets/音叶/旋钮9.png" class="icon-yydc"></img>
              <img src="./assets/音叶/旋钮8.png" class="icon-yydc"></img>
              <img src="./assets/音叶/旋钮7.png" class="icon-yydc"></img>
              <img src="./assets/音叶/旋钮6.png" class="icon-yydc"></img>
            </div>
            <svg :width="scrollWidth" height="200" style="margin-left: 0px;margin-top: 43px;">
              <line v-for="item in grid1" x1='30' :y1='item.posy' :x2='scrollWidth' :y2='item.posy' style='stroke-dasharray:3, 1; stroke: #515151; stroke-width:2; '/>
              <line v-for="(item, index) in pointList" :x1='(item.posx+73)' y1='0' :x2='(item.posx+73)' y2='185' style='stroke: #848983; stroke-width:2'/>
            </svg>
            <div id="pointDiv" class="point-ctn" :style="'width:' + scrollWidth" @mousedown="onMouseDown2">
              <div v-for="(item, index) in pointList" :key="item" @mousedown="onMouseDown($event, index)" class="point" :style="{left: item.posx + 'px' , top: item.posy + 'px' }">
                
              </div>
              <!--<el-checkbox class="cbox" v-for="(item, index) in pointList" :key="item" v-model="item.select" label="" :style="{left: item.posx2 + 'px' , top: item.posy2 + 'px' }" />-->
              <svg :width="scrollWidth" height="220">
                <path :d="pointStr" stroke="#79d572" stroke-width="3" fill="none"></path>
              </svg>
            </div>
          </div>
          
          <div style="position:relative;margin-top: 41px;margin-left: 0px;">
            <svg v-if="!isTranslate" :width="scrollWidth" height="200" style="position:absolute; margin-left: 0px;margin-top: 59px;">
              <line v-for="item in grid2" x1='20' :y1='item.posy' :x2='scrollWidth' :y2='item.posy' style='stroke-dasharray:3, 1; stroke: #515151; stroke-width:2; '/>
              <line v-for="(item, index) in pointList" :x1='(item.posx+73)' y1='0' :x2='(item.posx+73)' :y2='grid2LineHeight' style='stroke: #848b83; stroke-width:4'/>
            </svg>
            <svg v-if="isTranslate" :width="scrollWidth" height="200" style="position:absolute; margin-left: 0px;margin-top: 42px;">
              <line v-for="item in grid2" x1='20' :y1='item.posy+37' :x2='scrollWidth' :y2='item.posy+37' style='stroke-dasharray:3, 1; stroke: #515151; stroke-width:2; '/>
              <line v-for="(item, index) in pointList" :x1='(item.posx+73)' y1='0' :x2='(item.posx+73)' :y2='grid2LineHeight+37*2' style='stroke: #848b83; stroke-width:4'/>
            </svg>
            <div v-if="!isTranslate && langType != 'JP'" style="position:absolute;display: flex;flex-direction: column;top: 36px;">
              <img src="./assets/音叶/yd1.png" class="icon-yydc"></img>
              <img src="./assets/音叶/yd2.png" class="icon-yydc"></img>
              <img src="./assets/音叶/yd3.png" class="icon-yydc"></img>
              <img src="./assets/音叶/yd4.png" class="icon-yydc"></img>
              <img src="./assets/音叶/yd5.png" class="icon-yydc"></img>
            </div>
            <div v-if="isTranslate || langType == 'JP'" style="position:absolute;display: flex;flex-direction: column;top: 36px;">
              <img src="./assets/音叶/yd2.png" class="icon-yydc"></img>
              <img src="./assets/音叶/yd4.png" class="icon-yydc"></img>
            </div>
            <!--对应输入框的文字-->
            <div class="char-ctn">
              <div v-for="item in charList" class="char">{{ item.char }}</div>
            </div>
              
            <!--1~6个声调，中文-->
            <div v-if="!isTranslate" class="char-ctn" id="charEmo" style="margin-top: -4px;">
              <el-col v-for="(item, index) in charList" :span="0.1" >
                <div v-for="(item1, index1) in item.levels" class="char char-gd" @mousedown="handleMouseDown($event, index, index1)" @click="onLevelClick($event, index, index1)" :style="'opacity:' + item1.opacity">   
                  <img :src="item1.icon" class="icon-yydc2" @dragstart="preventDefault"></img>
                </div>
              </el-col>
              <img :src="charTempIcon" v-if="charTempFlag" class="char-temp" :style="'left:'+charTempX+';top:'+charTempY" @dragstart="preventDefault"></img>
            </div>
            <!--1~6个声调，日语-->
            <div v-if="isTranslate || langType == 'JP'" class="char-ctn" id="charEmo" style="margin-top: 13px;">
              <el-col v-for="(item, index) in charList" :span="0.1" >
                <div v-for="(item1, index1) in item.levels" class="char char-gd" @mousedown="handleMouseDown($event, index, index1)" @click="onLevelClick($event, index, index1)" :style="'opacity:' + item1.opacity">   
                  <img :src="item1.icon" class="icon-yydc2" @dragstart="preventDefault"></img>
                </div>
              </el-col>
              <img :src="charTempIcon" v-if="charTempFlag" class="char-temp" :style="'left:'+charTempX+';top:'+charTempY" @dragstart="preventDefault"></img>
            </div>

          </div>
        </el-scrollbar>
      </div>
      
      <div class="bottom-div">
        <AudioPlay ref="audioPlay" class="audio" :src="selectVoiceUrl"></AudioPlay>

        <div class="make-div">
          <StateButton class="make-btn" imgSrc="./assets/音叶/按钮-生成.png"  @click="onMakeClick"></StateButton>
          <div style="position: absolute; top: 60px; left: 0px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="makeSelected"  @change="onMakeCurSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">当前文本</el-text>
          </div>
          <div style="position: absolute; top: 60px; right: -25px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="!makeSelected"  @change="onMakeAllSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">所有文本</el-text>
          </div>
        </div>
        <div class="make-div2">
          <StateButton class="make-btn" imgSrc="./assets/音叶/按钮-下载.png"  @click="onDLoadClick"></StateButton>
          <div style="position: absolute; top: 60px; left: 0px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="downLoadSelected"  @change="onDLoadCurSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">当前语音</el-text>
          </div>
          <div style="position: absolute; top: 60px; right: -25px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="!downLoadSelected"  @change="onDLoadAllSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">所有语音</el-text>
          </div>
        </div>

        <!--<el-button @click="onSaveAll" type="info" class="save-all" :style="'left:'+testLeft1+';top:'+testTop1">保存所有语音</el-button>
        <div class="make-div" :style="'left:'+testLeft2+';top:'+testTop2">
          <StateButton class="make-cur" imgSrc="./assets/音叶/按钮-生成当前文本语音.png"  @click="onMakeCur"></StateButton>
          <StateButton class="make-all" imgSrc="./assets/音叶/按钮-生成所有文本语音.png"  @click="onMakeAll"></StateButton>
        </div>-->
      </div>
      <!--<div class="myprogress">
        <MyProgress ></MyProgress>
      </div>-->
    </div>

    <div class="right">
      <el-scrollbar class="scroll-right" width="100%" max-height="100%">
        <div class="right2">
          <div class="translate">
            <StateButton class="translate-btn" :imgSrc="baseUrl + '/assets/音叶/翻译开关.png'" :isState2="true"  @change="onTranslate"></StateButton>
            <el-text class="set-text2" style="position:absolute;top:-2px;">翻译</el-text>
          </div>
          <!--<el-checkbox label="日语翻译" v-model="isTranslate" class="translate" @change="onTranslate" />-->
        <!--下拉选项-->
        <el-container class="test">
          <el-container class="">
            <el-text class="set-text2">使用场景</el-text>
          </el-container>
          <el-select v-model="selectObj1" @change="onLangSelect" placeholder="Select" class="custom-select-color" size="small" placement="bottom-end" :teleported="false">
            <el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-container>

        <el-container class="test">
          <el-container class="">
            <el-text class="set-text2">配音员</el-text>
          </el-container>
          <el-select v-model="selectObj2" @change="onVoiceSelect" class="custom-select-color" placeholder="Select" size="small" placement="bottom-end" style="width: 100%" :teleported="false">
            <el-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-container>

        <el-container class="test">
          <el-container class="">
            <el-text class="set-text2">情绪设置</el-text>
          </el-container>
          <el-select v-model="selectObj3" @change="onEmoSelect" class="custom-select-color" placeholder="Select" size="small" placement="bottom-end" style="width: 100%" :teleported="false">
            <el-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-container>
        
        <!--滑块-->
        <el-container v-for="(item, index) in sliderList"  class="test">
          <el-container class="">
            <el-text class="set-text2">{{item.name}}</el-text>
          </el-container>
          <!--<el-slider v-model="item.value" show-input :show-input-controls="true" size="small" input-size="small" class="slider" />-->
          <MyProgress class="myprogress" :value="item.value" :min="item.min" :max="item.max" @change="onSlider($event, index)"></MyProgress>
        </el-container>
      </div>
      </el-scrollbar >
    </div>
    
    <div class="mask-ctn" v-if="isGenerating">
      <div class="mask"></div>
      <div>sdds</div>
      <el-text class="mask-txt">{{ generateStr }}</el-text>
    </div>
  </div>

  <!--手机移动端-->
  <div class="m-mobile">
  <div v-if="isMobile" class="m-div-ctn" @mouseup="onMouseUp($event)">
    <van-config-provider theme="dark"></van-config-provider>
      <div class="m-content" style="margin-top: 10px;">
        <div class="scroll-container" id="scrollArea" scrollColor="#3a405bFF" :style="'height:' + inputHeight + 'px;width:100%;margin-left:0px;'">
          <el-container class="input-ctn" :style="'height:'+(inputCtnHeight+6)+'px'" v-for="(item, index) in inputList" :key="item">
            <van-swipe-cell :style="'width: 100%;height:'+(inputCtnHeight+16)+'px'">
              <img src="./assets/音叶/mobile/图标-选中.png" style="width: 16px;height: 25px;margin-top: 38px;margin-left: 10px;" v-if="item.select"></img>
              <div class="input-ctn2" :style="'height:'+inputCtnHeight+'px;width:92%;left:5%;top:10px;border-radius:5px;'">
                <el-input v-model="item.value" type="textarea" class="borderless2" :input-style="m_inputStyle"  @focus="onFocus($event, index)" @input="onInput($event, index)" placeholder="请输入文本内容" />
                
                <div v-if="isTranslate" class="jap-ctn">
                  <div class="jap-line"></div>
                  <el-input v-model="item.japStr" type="textarea" class="borderless2" :input-style="m_inputStyle2" :disabled="true" />
                </div>
                <div class="input-tag m-input-tag" style="background-color:#2e2e2e;">文本{{ index+1 }}</div>
              </div>
              <template #right>
              <StateButton style="width: 39px;height: 40.33px;margin-left: -5px;margin-top: 35px;" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-左滑删除文本.png'"  @click="onDelete($event, index)"></StateButton>
              </template>
            </van-swipe-cell>
          </el-container>
        </div>
        <div style="position: relative;margin-top: 10px;width: 100%;margin-left: 20px;">
          <StateButton class="m-translate-btn" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-翻译开启关闭.png'" :isState2="true"  @change="onTranslate"></StateButton>
          <el-text class="set-text-normal" style="position:absolute;top:-2px;left: 90px;">翻译</el-text>
          
          <div style="position: absolute;top: 0px;left: 250px;width: 200px;">
            <StateButton style="width: 32px;height: 33.33px" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-下载.png'"  @click="onSaveAll"></StateButton>
            <el-text class="set-text-normal" style="color: white; position: absolute;left: 35px;top: 0px;">下载全部音频</el-text>
          </div>
          <div style="position: absolute;top: 0px;right: 0px;width: 200px;">
            <StateButton style="width: 32px;height: 33.33px" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-添加新文本.png'"  @click="add($event, 'param test')"></StateButton>
            <el-text class="set-text-normal" style="color: white; position: absolute;left: 35px;top: 0px;">添加文本</el-text>
          </div>
        </div>
        <div style="width: 100%;height:10px;"></div>
      </div>

      <div class="m-content">
        <AudioPlay2 ref="audioPlay" class="m-audio" :src="selectVoiceUrl"></AudioPlay2>
        <StateButton style="position:absolute;width: 32px;height: 33.33px;right:10px;top:10px;" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-下载.png'"  @click="onDLoadClick"></StateButton>
      </div>
      <div style="margin-top: 10px;">
        <el-radio-group v-model="radio1" size="large">
          <StateButton style="position:relative;width: 166px;height: 63px;top:10px;" :selected="!isVoiceSelect" :isState2="true" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-抑扬顿挫.png'"  @click="onClickYYDC"></StateButton>
          <StateButton style="position:relative;width: 166px;height: 63px;top:10px;" :selected="isVoiceSelect" :isState2="true" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-音调.png'"  @click="onClickVoice"></StateButton>
        </el-radio-group>
        <StateButton style="position:relative;width: 159px;height: 60px;margin-top:-58px;margin-left: 400px;" :selected="isVoiceSelect" :imgSrc="baseUrl + '/assets/音叶/mobile/按钮-生成.png'"  @click="onMakeClick"></StateButton>
      </div>
      <div class="m-content">
        <div class="scroll-container" id="charScroll" scrollColor="#3a405bFF" :style="'height:' + charScrollH + 'px;width:100%;margin-left:0px;'">
        <!--<el-scrollbar ref="myScroll" id="scrollId" class="m-scrollbar" :style="'height:'+300+'px;position:relative'" :always="true" height="300px">-->
          <!--抑扬顿挫-->
          <div v-if="!isVoiceSelect" style="position: relative;width: 100%">
            <!--对应输入框的文字-->
            <div class="m-char-ctn">
              <div v-for="item in charList" class="m-char" style="height: 50px;">{{ item.char }}</div>
            </div>
            <div v-if="!isTranslate" class="m-char-ctn" id="charEmo" style="margin-top: 0px;">
              <el-col v-for="(item, index) in pointList" :span="0.1" > 
                <div v-for="(item1, index1) in item.icons" class="m-char" >
                  <StateButton style="position:relative;width: 67px;height: 61.5px;" :selected="!(item1.selected)" :isState3="true" :imgSrc="item1.url" @touchend="yydcTouchEnd($event, index, index1)"></StateButton>
                </div>
              </el-col>
            </div>
          </div>
          
          <!--音调-->
          <div v-if="isVoiceSelect" style="position:relative;margin-top: 0px;margin-left: 0px;">
            <!--对应输入框的文字-->
            <div class="m-char-ctn">
              <div v-for="item in charList" class="m-char" style="height: 50px;">{{ item.char }}</div>
            </div>
              
            <!--1~6个声调，中文-->
            <div v-if="!isTranslate" class="m-char-ctn" id="charEmo" style="margin-top: 0px;">
              <el-col v-for="(item, index) in charList" :span="0.1" >
                <div v-for="(item1, index1) in item.levels" class="m-char" @mousedown="handleMouseDown($event, index, index1)" @click="onLevelClick($event, index, index1)">   
                  <!--<img :src="item1.icon" class="icon-yydc2" @dragstart="preventDefault"></img>-->
                  <StateButton style="position:relative;width: 75px;height: 63.5px;" :selected="!item1.select" :isState2="true" :imgSrc="item1.icon"></StateButton>
                </div>
              </el-col>
              <!--<img :src="charTempIcon" v-if="charTempFlag" class="char-temp" :style="'left:'+charTempX+';top:'+charTempY" @dragstart="preventDefault"></img>-->
            </div>
            <!--1~6个声调，日语-->
            <div v-if="isTranslate" class="char-ctn" id="charEmo" style="margin-top: 13px;">
              <el-col v-for="(item, index) in charList" :span="0.1" >
                <div v-for="(item1, index1) in item.levels" class="char char-gd" @mousedown="handleMouseDown($event, index, index1)" @click="onLevelClick($event, index, index1)" :style="'opacity:' + item1.opacity">   
                  <img :src="item1.icon" class="icon-yydc2" @dragstart="preventDefault"></img>
                </div>
              </el-col>
              <img :src="charTempIcon" v-if="charTempFlag" class="char-temp" :style="'left:'+charTempX+';top:'+charTempY" @dragstart="preventDefault"></img>
            </div>

          </div>
        </div>
        <!--</el-scrollbar>-->
      </div>
      
      <!--<div class="bottom-div">

        <div class="make-div">
          <StateButton class="make-btn" imgSrc="./assets/音叶/按钮-生成.png"  @click="onMakeClick"></StateButton>
          <div style="position: absolute; top: 60px; left: 0px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="makeSelected"  @change="onMakeCurSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">当前文本</el-text>
          </div>
          <div style="position: absolute; top: 60px; right: -25px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="!makeSelected"  @change="onMakeAllSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">所有文本</el-text>
          </div>
        </div>
        <div class="make-div2">
          <StateButton class="make-btn" imgSrc="./assets/音叶/按钮-下载.png"  @click="onDLoadClick"></StateButton>
          <div style="position: absolute; top: 60px; left: 0px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="downLoadSelected"  @change="onDLoadCurSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">当前语音</el-text>
          </div>
          <div style="position: absolute; top: 60px; right: -25px; width: 50%;">
            <StateButton class="make-cur" :imgSrc="baseUrl + '/assets/音叶/选择文本按钮.png'" :isState2="true" :selected="!downLoadSelected"  @change="onDLoadAllSelect"></StateButton>
            <el-text class="set-text3" style="position:absolute;top:-3px;left: 25px;">所有语音</el-text>
          </div>
        </div>
      </div>-->

    <div class="m-content" v-if="!mIsOpen">
      <img src="./assets/音叶/mobile/按钮-下箭头.png" style="width: 33px;height: 30px;margin-left: calc(50% - 16px);margin-top: 10px;" @click="onOpenClick"></img>
    </div>
    <div class="m-content" v-if="mIsOpen">
          <!--<el-checkbox label="日语翻译" v-model="isTranslate" class="translate" @change="onTranslate" />-->
        <img src="./assets/音叶/mobile/按钮-下箭头.png" style="width: 33px;height: 30px;margin-left: calc(50% - 16px);margin-top: 10px;transform: rotate(180deg)" @click="onCloseClick"></img>
        <div class="scroll-container" id="attrScroll" scrollColor="#3a405bFF" :style="'height:350px;width:100%;margin-left:0%;'">
          <div style="width:96%;margin-left:3%;">
            <!--下拉选项-->
            <el-container class="m-test" style="margin-top: -5px;">
              <el-container class="">
                <el-text class="set-text2">使用场景</el-text>
              </el-container>
              <el-select v-model="selectObj1" @change="onLangSelect" placeholder="Select" class="custom-select-color" size="large" placement="bottom-end" :teleported="false">
                <el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-container>

            <el-container class="m-test">
              <el-container class="">
                <el-text class="set-text2">配音员</el-text>
              </el-container>
              <el-select v-model="selectObj2" @change="onVoiceSelect" class="custom-select-color m-custom-select-color2" placeholder="Select" size="large" placement="bottom-end" style="width: 100%" :teleported="false">
                <el-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-container>

            <el-container class="m-test">
              <el-container class="">
                <el-text class="set-text2">情绪设置</el-text>
              </el-container>
              <el-select v-model="selectObj3" @change="onEmoSelect" class="custom-select-color m-custom-select-color3" placeholder="Select" size="large" placement="bottom-start" style="width: 100%" :teleported="false">
                <el-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-container>
            
            <!--滑块-->
            <div v-for="(item, index) in sliderList" style="height: 50px;width:100%;position: relative;margin-top: 10px;">
              <div class="set-text2">{{item.name}}</div>
              <!--<el-slider v-model="item.value" show-input :show-input-controls="true" size="small" input-size="small" class="slider" />-->
              <MyProgress2 class="m-myprogress" :value="item.value" :min="item.min" :max="item.max" @change="onSlider($event, index)"></MyProgress2>
            </div>
          </div>
        </div>
        
    </div>
    
    <div class="m-mask-ctn" v-if="isGenerating">
      <div class="mask"></div>
      <div>sdds</div>
      <el-text class="m-mask-txt">{{ generateStr }}</el-text>
    </div>
  </div>
  </div>

</template>

<script setup lang="ts">
  import { ref, onMounted, reactive, provide } from 'vue';
  import { StarFilled } from '@element-plus/icons-vue';
  import AudioPlay from './components/AudioPlay.vue';
  import AudioPlay2 from './components/AudioPlay2.vue';
  import MyProgress from './components/MyProgress.vue';
  import MyProgress2 from './components/MyProgress2.vue';
  import StateButton from './components/StateButton.vue';
  // import MyScroll from './components/MyScroll.vue';
  import { ElMessage } from 'element-plus';
    //import * as WebSocket from 'websocket';
  import { ElSelect, ElOption } from 'element-plus';

  function testaaa() {
    // var csv = '姓名,期中成绩,期末成绩\n张三,58,95\n李四,98,74';
    // var a = document.createElement('a');
    // // a.href = 'text/csv;charset=utf-8,' + encodeURIComponent(csv);
    // a.href = URL.createObjectURL('https://www.shiyinren.com/server/1/221822646.mp3');
    // // a.download = '测试.csv';
    // a.download = '可能.mp3';
    // document.body.appendChild(a);
    // a.click();
    // document.body.removeChild(a);
}

  var env = import.meta.env;
  console.log('env=',env);
  var baseUrl = ''
  if (env.MODE == 'development') {
    baseUrl = './src';
  }
  else{
    baseUrl = env.VITE_PUBLIC_PATH;
  }

  const power:number = 0.8;//
  const step:number = 0.1;//
  const maxPosy:number = 185;
  const pointW:number = 51;
  let selectIndex:number = 0;
  let selectText:string = '';
  const inputScroll = ref(null);
  const audioPlay = ref(null);

  const inputList = ref([{value:"",select:true,over:false, japStr:''}])
  const inputStyle = ref({color:'#ffffff','background-color': '#2e2e2e', left:'10px', top:'10px', width:'90%', height:'60px'});
  const inputStyle2 = ref({color:'#ffffff','background-color': '#2e2e2e', left:'10px', top:'0px', width:'90%', height:'25px'});

  const m_inputStyle = ref({color:'#ffffff','background-color': '#2e2e2e', left:'10px', top:'10px', width:'90%', height:'60px'});
  const m_inputStyle2 = ref({color:'#ffffff','background-color': '#2e2e2e', left:'10px', top:'0px', width:'90%', height:'25px'});

  let list:any = [];//{value:5}
  let str:string = "";
  for(var i=0; i<list.length; i++){
    list[i].posx = 50 * (i + 1);
    list[i].posy = 180;
    list[i].posx2 = 50 * (i + 1);
    list[i].posy2 = 210;

    list[i].tempy = 180;
    list[i].select = false;
    list[i].level = 1;
    list[i].icons = [];

    // console.log(list[i].posx);

    if(i == 0){
      str = "M " + (list[0].posx+10) + " " + (list[0].posy+15);
    }
    str += " L " + (list[i].posx+10) + "," + (list[i].posy+15) + " ";
  }
  let pointStr:any = ref(str);
  let pointList:any = ref(list);
  const pointDic:Array<any> = [];
  pointDic.push(pointList.value);
  const input = ref('');
  const selectObj1 = ref('中文');
  const selectObj2 = ref('adachi');
  const selectObj3 = ref('Neutral');
  const selectDic = [{select1:'中文', select2:'adachi', select3:'Neutral'}];
  const langType = ref('ZH');

  const sliderObj = ref(10);
  const charList = ref([{char:"",levels:[{bgcolor:"white",select:false,opacity:0.01,icon:''}],default:[]}]);
  const charTempFlag = ref(false);
  const charTempIcon = ref('');
  const charTempX = ref('');
  const charTempY = ref('');
  const charScrollH = ref(475);
  let charTempStart:number = 0;
  let charTempIdx1:any;
  let charTempIdx2:any;
  let charTempObj:any;
  const testUrl = ref('@/assets/音叶/ydset1.png');
  const charLevelDic:any[] = [];//对应输入框，保存每个字的声调1~6声的数组

  let charLevDataList:any[] = [];//索引对应每个输入框，保存的是以下的变量
  let charLevData:any = {};//服务器返回的默认设置，对应每个字
  let charVoiceDataList:any[] = [];//索引对应每个输入框，保存的是以下的变量
  let charVoiceData:any[] = [];//服务器返回的声音文件，url路径，duration时长
  const selectVoiceUrl = ref('');
  

  const myScroll = ref(null);
  const scrollWidth = ref("100%");
  const showSet = ref(true);
  const INPUT_MIN_H:number = 220;
  const inputHeight = ref(INPUT_MIN_H);
  const inputCtnHeight = ref(74);
  const isGenerating = ref(false);
  const generateStr = ref('');
  let generateNum:number = 1;
  let generateCount:number = 0;
  let generateArr:number[] = [];
  let generateError:number = 0;
  const testLeft1 = ref('460px');
  const testTop1 = ref('0px');
  const testLeft2 = ref('80%');
  const testTop2 = ref('0px');
  const makeSelected = ref(true);
  const downLoadSelected = ref(true);
  
  const session_hash = '06bbw682nw' + Math.floor(Math.random()*100);
  const modelUrl = ref('model_assets\\model_zh\\model_zh_e10_s19000.safetensors');

  const gridHeight = 37;
  const gridWidth = 51;
  var arr = [];
  for(var i=0; i<6; i++){
    arr.push({posy:(i * gridHeight)});
  }
  const grid1 = ref(arr);
  var arr = [];
  for(var i=0; i<5; i++){
    arr.push({posy:(i * gridHeight)});
  }
  const grid2 = ref(arr);
  const grid2LineHeight = ref(148);

  const sliderFlag = false;
  let isDrag:boolean = false;
  let prtDom:DOMRect;
  let dIndex:number = 0;
  let tempPosy:number = 0;

  str = "";
  let speed:number = 20;
  let g:number = 2;
  let li:number = 0;
  let cur:number = 180;
  let list2:any = [];
  for(var i=0; i<100; i++){
    list2[i] = {};
    list2[i].posx = 10 + (i * 10);

    list2[i].posy = cur;
    cur -= speed;
    speed -= g;
    

    if(i == 0){
      str = "M " + (list2[0].posx+10) + " " + (list2[0].posy+15);
    }
    str += " L " + (list2[i].posx+10) + "," + (list2[i].posy+15) + " ";
  }
  const TestStr = ref(str);
  const isTranslate = ref(false);
  const translateStr = ref('');
  const setHeight = ref(570);
  const emoHeight = ref(242);
  const scrollHeight = ref(531);
  const isMobile = ref(false);//手机
  const isTablet = ref(false);//平板
  const isVoiceSelect = ref(false);
  const radio1 = ref('type1')
  const sizeStr = ref('')
  let isCharTouchMove:boolean = false;
  const mIsOpen = ref(true);

  onMounted(() => {
    
    let str2:string = window.innerWidth+","+window.innerHeight;
    sizeStr.value = str2;
    console.log(str2);

    const width = document.body.clientWidth || window.innerWidth
    const scale = width / 750;
    const content = `width=750, initial-scale= ${scale}, minimum-scale= ${scale}, maximum-scale= ${scale}, viewport-fit=cover`
    
    if(isMobile.value){
      if(document){
        document.querySelector( 'meta[name="viewport"]').content = content
      }
    }

    refreshInputHeight();

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
    window.addEventListener('resize', onResize);
    onResize();

    if(isMobile.value){
      onTouchMove('scrollArea');
      onTouchMove('charScroll', true);
      onTouchMove('attrScroll');
    }

    httpLogin();

  });

  function onOpenClick(){
    mIsOpen.value = true;
  }
  function onCloseClick(){
    mIsOpen.value = false;
  }
  function onSlider(event:any, index:any){
    // console.log('滑块变化：', event, index);
    // console.log('滑块变化1：', sliderList.value);
    sliderList.value[index].temp = event;
  };
  function onTouchMove(id:string, isX:boolean = false){
    const scrollArea = document.getElementById(id);
    if(isX){
      let startX:number, endX, distance;
      
      if(scrollArea){
        scrollArea.addEventListener('touchstart', function(e) {
          startX = e.touches[0].pageX;
          console.log('startX=',startX)
        });
      
        scrollArea.addEventListener('touchmove', function(e) {
          e.preventDefault(); // 防止页面滚动
          endX = e.touches[0].pageX;
          console.log('endX=',endX)
          distance = endX - startX;
          scrollArea.scrollLeft -= distance;
          startX = endX;
          isCharTouchMove = true;
        });
      }
    }
    else{
      let startY:number, endY, distance;
      
      if(scrollArea){
        scrollArea.addEventListener('touchstart', function(e) {
          startY = e.touches[0].pageY;
        });
      
        scrollArea.addEventListener('touchmove', function(e) {
          e.preventDefault(); // 防止页面滚动
          endY = e.touches[0].pageY;
          distance = endY - startY;
          scrollArea.scrollTop -= distance;
          startY = endY;
        });
      }
    }
  };
  const checkDeviceType = () => {
    const userAgent = navigator.userAgent || navigator.vendor;// || window.opera;

    if (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)) {
      isMobile.value = true;
      provide('isMobile', true);
    } else if (/firefox|msie|trident|edge/i.test(userAgent)) {
      isTablet.value = true;
    }

    if(isMobile.value){
      inputCtnHeight.value = 79;
    }
    else{
      inputCtnHeight.value = 74;
    }
  };
  
  checkDeviceType();

  

  const list11 = ref([0]);
    const loading = ref(false);
    const finished = ref(false);

    const onLoad = () => {
      // 异步更新数据
      // setTimeout 仅做示例，真实场景中一般为 ajax 请求
      setTimeout(() => {
        for (let i = 0; i < 10; i++) {
          list11.value.push(list11.value.length + 1);
        }

        // 加载状态结束
        loading.value = false;

        // 数据全部加载完成
        if (list11.value.length >= 40) {
          finished.value = true;
        }
      }, 1000);
    };
    
  const handleScroll = (event:any) => {
    // 获取滚动位置
    const scrollTop = event.target.scrollTop;
    console.log('滚动位置:', scrollTop);
    
    // 你可以在这里根据滚动位置进行相应的处理
  };

  function onClickYYDC(){
    isVoiceSelect.value = false;
    charScrollH.value = 475;
  }
  function onClickVoice(){
    isVoiceSelect.value = true;
    charScrollH.value = 410;
  }

  function onDLoadCurSelect(selected:boolean){
    if(selected){
      downLoadSelected.value = true;
    }
  }
  function onDLoadAllSelect(selected:boolean){
    if(selected){
      downLoadSelected.value = false;
    }
  }
  function onMakeCurSelect(selected:boolean){
    if(selected){
      makeSelected.value = true;
    }
  }
  function onMakeAllSelect(selected:boolean){
    if(selected){
      makeSelected.value = false;
    }
  }
  function onTranslate(selected:boolean){
    // console.log("ldskdslldslds", isTranslate.value);

    isTranslate.value = selected;

    let style:any = inputStyle.value;
    var arr = grid2.value;
    arr.length = 0;
    if(isTranslate.value){//翻译成日语
      for(var i=0; i<2; i++){
        arr.push({posy:(i * gridHeight)});
      }
      grid2LineHeight.value = 37;

      inputCtnHeight.value = isMobile.value ? 101 : 96;
      
      style.height = '25px';
          
      setHeight.value = 570 - 72;
      emoHeight.value = 242 - 72;
      scrollHeight.value = 531 - 72;
    }
    else{//默认中文
      for(var i=0; i<5; i++){
        arr.push({posy:(i * gridHeight)});
      }
      grid2LineHeight.value = 148;

      inputCtnHeight.value = isMobile.value ? 79 : 74;
      style.height = '60px';
      
      setHeight.value = 570;
      emoHeight.value = 242;
      scrollHeight.value = 531;
    }
    refreshInputHeight();
  }
  function onLangSelect(value:any){
    console.log('语言',value);
    langType.value = value;

    var arr = grid2.value;
    arr.length = 0;
    if(langType.value == 'JP'){//翻译成日语
      for(var i=0; i<2; i++){
        arr.push({posy:(i * gridHeight)});
      }
      grid2LineHeight.value = 37;
          
      setHeight.value = 570 - 72;
      emoHeight.value = 242 - 72;
      scrollHeight.value = 531 - 72;
    }
    else{//默认中文
      for(var i=0; i<5; i++){
        arr.push({posy:(i * gridHeight)});
      }
      grid2LineHeight.value = 148;
      
      setHeight.value = 570;
      emoHeight.value = 242;
      scrollHeight.value = 531;
    }
  }
  
  function onVoiceSelect(){
    // selectObj3.value = "Neutral";
    
    updateSelectObj();
  }
  function onEmoSelect(){
    updateSelectObj();
  }
  function updateSelectObj(){
    var selectObj = selectDic[selectIndex];
    if(selectObj){
      selectObj.select1 = selectObj1.value;
      selectObj.select2 = selectObj2.value;
      selectObj.select3 = selectObj3.value;
    }
  }
  function onMakeClick(){
    if(makeSelected.value){
      onMakeCur();
    }
    else{
      onMakeAll();
    }
  }
  function onMakeCur(){
    let inputs:any = inputList.value;
    let str:string = inputs[selectIndex].value;
    if(!str){
      ElMessage({
          message: '请在输入框中输入文本内容！',
          type: 'error',
      })
      return;
    }

    generateNum = 1;
    generateCount = 0;
    generateStr.value = "语音生成中（0/"+generateNum+"）。。。";
    makeSingle(selectIndex);

    generateError = setTimeout(onGenerateError, generateNum * 15000);
  }
  function onGenerateError(){
    ElMessage({
        message: '语音生成出错！请重试！',
        type: 'error',
    })
    generateCount = generateNum;
    isGenerating.value = false;
    generateError = 0;
  }
  function makeSingle(index:number){
    // let inputs:any = inputList.value;
    // let str:string = inputs[index].value;
    // if(!str){
    //   return;
    // }

    // var list = pointList.value;
    // let arr:string[] = [];
    // for(var i=0; i<list.length; i++){
    //   arr.push(list[i].level);
    // }
    // var yydcStr = JSON.stringify(arr);//抑扬顿挫"[2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1]";//
    // var info = charLevDataList[selectIndex];
    // var sdStr;
    // var translate = info.translate ? true : false;
    // if(translate){//日语
    //   sdStr = info.str;
    // }
    // else{
    //   sdStr = JSON.stringify(info.obj);
    // }

    // var obj = [
    //     translate,
    //     selectObj2.value,//"Hanazawa_Sakura_ana",
    //     selectObj3.value,//"悲伤",
    //     str,//"我是谁？我在哪？晚上吃什么?",
    //     yydcStr,//"[2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1]",
    //     sdStr,//"[{\"我\":{\"w o\":3}},{\"是\":{\"sh ir\":4}},{\"谁\":{\"sh ui\":2}},{\"?\":{}},{\"我\":{\"w o\":3}},{\"在\":{\"z ai\":4}},{\"哪\":{\"n a\":3}},{\"?\":{}},{\"晚\":{\"w an\":3}},{\"上\":{\"sh ang\":4}},{\"吃\":{\"ch ir\":1}},{\"什\":{\"sh en\":2}},{\"么\":{\"m e\":5}},{\"?\":{}},{\"啊\":{\"AA a\":5}}]",
    //     "zh"
    // ];

    // var sdata = {data:obj,"event_data":null,"fn_index":3,"session_hash":session_hash};
    // connectSocket(3, index, sdata, isTranslate.value);

    
    let inputs:any = inputList.value;
    let str:string = inputs[index].value;
    if(!str){
      return;
    }

    var list = pointList.value;
    let arr:string[] = [];
    for(var i=0; i<list.length; i++){
      arr.push(list[i].level);
    }
    var yydcStr = JSON.stringify(arr);//抑扬顿挫"[2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1]";//
    var info = charLevDataList[selectIndex];
    var sdStr;
    var translate = false;
    if(info){
      translate = info.translate ? true : false;
      if(translate){//日语
        sdStr = info.str;
      }
      else{
        sdStr = JSON.stringify(info.obj);
      }
    }
    else{
      sdStr = '';
    }
    var sdata:any = ["model_zh", 
                      modelUrl.value, 
                      str, 
                      langType.value, 
                      selectObj3.value,
                      Math.floor(sliderList.value[0].temp),
                      sdStr,
                      selectObj2.value
    ];
    connectSocket(0, index, sdata, str, isTranslate.value);
  }
  function onMakeAll(){
    let inputs:any = inputList.value;
    var len = inputs.length;
    let arr:any = [];
    for(var i=0; i<len; i++){
      let str:string = inputs[i].value;
      if(!str){
        continue;
      }
      arr.push(i);
    }
    if(arr.length <= 0){
      ElMessage({
          message: '没有可生成的语音，请先输入文本内容。',
          type: 'error',
      })
      return;
    }
    generateNum = arr.length;
    generateCount = 0;
    generateStr.value = "语音生成中（0/"+generateNum+"）。。。";
    generateArr = arr;
    makeSingle(generateCount);

    generateError = setTimeout(onGenerateError, generateNum * 15000);
  }
  
  function onResize(){
    // console.log("sdkdsldsldsl")
    let div:any = document.getElementById('leftDiv');
    if(!div){
      return;
    }
    var rect = div.getBoundingClientRect();
    if(rect.width < 910){
      testLeft1.value = '32px';
      testTop1.value = '130px';
      testLeft2.value = '223px';
      testTop2.value = '130px';
    }
    else{
      testLeft1.value = '460px';
      testTop1.value = '0px';
      testLeft2.value = (rect.width - 275) + 'px';
      testTop2.value = '0px';
    }
  }
  function onHideSet(){
    showSet.value = false;
    refreshInputHeight();
  }
  function onShowSet(){
    showSet.value = true;
    refreshInputHeight();
  }
  
  function initPoints2(chars:string, levels:any = null){//移动端
    let list:any = pointList.value;//[];//{value:5}
    let str:string = "";
    let sw:number = 0;
    console.log('levels=====', levels)
    for(var i=0; i<chars.length; i++){
      if(list[i] == null){
        list[i] = {};
        list[i].select = false;
        list[i].level = levels != null ? levels[i] : 1;
        var arr:any = [];
        list[i].icons = arr;
        for(var j=0; j<6; j++){
          arr.push({url:baseUrl + '/assets/音叶/mobile/抑扬顿挫-'+(j+1)+'.png', selected:(list[i].level == (j+1))});
        }
      }
      else{
      }
    }
    for( ; i<list.length; i++){
      list.splice(i, 1);
      i --;
    }
  }
  function initPoints(chars:string, levels:any = null){
    if(isMobile.value){
      initPoints2(chars, levels);
      return;
    }
    let list:any = pointList.value;//[];//{value:5}
    let str:string = "";
    let sw:number = 0;
    console.log('levels=====', levels)
    for(var i=0; i<chars.length; i++){
      if(list[i] == null){
        list[i] = {};
        list[i].posx = 16 + pointW * (i);
        list[i].posx2 = list[i].posx;
        list[i].posy2 = 210;

        list[i].select = false;
        list[i].level = levels != null ? levels[i] : 1;

        var py = maxPosy - (list[i].level-1) * gridHeight;
        list[i].posy = py;
        list[i].tempy = py;
      }
      else{
        var py = maxPosy - (list[i].level-1) * gridHeight;
        list[i].posy = py;
        list[i].tempy = py;
      }

      // console.log(list[i].posx);

      if(i == 0){
        str = "M " + (list[0].posx+10) + " " + (list[0].posy+15);
      }
      str += " L " + (list[i].posx+10) + "," + (list[i].posy+15) + " ";

      sw = list[i].posx + 25;
    }
    for( ; i<list.length; i++){
      list.splice(i, 1);
      i --;
    }
    pointStr.value = str;
    // pointList.value = list;

    let scroll:any = document.getElementById("scrollId");
    // console.log(boxWidth.clientWidth);
    if(sw < scroll.clientWidth){
      sw = scroll.clientWidth;
    }
    else{
      sw += 100;
    }
    scrollWidth.value = sw + "px";

    // let scroll:any = myScroll.value;
    // if(scroll){
    //   // scrollWidth = scroll.width + "px";
    //   console.log(scroll.offsetWidth);
    // }
  }
  
  function onMouseDown2(e:any){
    if(!isDrag){
      let div:any = document.getElementById('pointDiv');

      prtDom = div.getBoundingClientRect();
      var vx = e.clientX - prtDom.left;
      dIndex = Math.floor((vx + 0) / gridWidth);

      let list:any = pointList.value;
      tempPosy = list[dIndex].posy;
      
      var posy = e.clientY - prtDom.top;
      onMouseMove2(posy);
      isDrag = true;
      onMouseUp(null);
    }
  }
  function onMouseDown(e:any, idx:any){
    if(!isDrag){
      isDrag = true;
      prtDom = e.target.parentNode.getBoundingClientRect();
      //console.log(prtDom);//
      dIndex = idx;
      
      tempPosy = e.clientY - prtDom.top;
      // tempPosy = pointList.value[dIndex].posy;
      console.log("mouse onMouseDownonMouseDown------>",tempPosy,pointList.value[dIndex].posy);
      
      // let list:any = pointList.value;
      // for(var i=0; i<list.length; i++){
      //   list[i].tempy = list[i].posy;
      //   list[i].step = 0.3;
      //   list[i].g = 0.02;
      // }
      
      window.addEventListener('mousemove', onMouseMove);
      window.addEventListener('mouseup', onMouseUp);
    }
  }
  function getPower(index:number){
    let cur:number = 0.6;
    let speed:number = 0.16;
    let g:number = 0.03;

    for(var i=0; i<index; i++){
      cur -= speed;
      speed -= g;
      
      if(speed < 0){
        speed = 0;
      }
    }
    if(cur < 0){
      cur = 0;
    }
    // console.log("---------->"+cur)
    return cur;
  }
  function onMouseMove(e:any){
    if(isDrag){
      let posy:number = e.clientY - prtDom.top;
      onMouseMove2(posy);
    }
  }
  function onMouseMove2(posy:number){
    const minValue = 0;
      let list:any = pointList.value;
      let item:any = list[dIndex];
      const offy = 14;
      if(posy > maxPosy+offy){
        posy = maxPosy+offy;
      }
      if(posy < minValue+offy){
        posy = minValue+offy;
      }
      item.posy = posy - offy;
      const disvalue:number =  posy - tempPosy;
      console.log('抑扬顿挫,disvalue=',disvalue);

      let index:number = 0;
      let temp:number = 0;
      // let flag:boolean = false;
      for(var i=dIndex+1; i<list.length; i++){
        if(!list[i].select){
            index ++;
            // temp = list[i].tempy + (posy-list[i].tempy) * (getPower(index));
            temp = list[i].tempy + (disvalue) * (getPower(index));
            if(temp > maxPosy){
              temp = maxPosy;
            }
            if(temp < minValue){
              temp = minValue;
            }
            console.log('temp',temp);
            list[i].posy = temp;
          }
          else{
            break;
          }
      }
      index = 0;
      for(i=dIndex-1; i>=0; i--){
        if(!list[i].select){
            index ++;
            // temp = list[i].tempy + (posy-list[i].tempy) * (getPower(index));
            temp = list[i].tempy + (disvalue) * (getPower(index));
            if(temp > maxPosy){
              temp = maxPosy;
            }
            if(temp < minValue){
              temp = minValue;
            }
            console.log('temp',temp);
            list[i].posy = temp;
          }
          else{
            break;
          }
      }
      //console.log(item);

      let str:string = "";
      for(i=0; i<list.length; i++){
        //M 60 180 Q 110,180 160,85
        if(i == 0){
          str = "M " + (list[0].posx+10) + " " + (list[0].posy+15);
        }
        str +=  " L " + (list[i].posx+10) + "," + (list[i].posy+15) + " ";
        // if(i == 0){
        //   str = "M " + (list[0].posx+10) + " " + (list[0].posy);
        // }
        // str +=  " L " + (list[i].posx+10) + "," + (list[i].posy) + " ";

        //str += "M " + (list[i].posx+10) + " " + (list[i].posy+10) + " Q" + (list[i].posx+60) + " " + (list[i].posy) + " " + (list[i+1].posx+10) + "," + (list[i+1].posy+10) + " ";
      }
      pointStr.value = str;
  }
  function onMouseUp(e:any){
    if(isDrag){
      isDrag = false;
      console.log("mouse upupupupup------>");
      let list:any = pointList.value;
      
      if(dIndex != -1){
        // list[dIndex].select = true;
        dIndex = -1;
      }

      for(var i=0; i<list.length; i++){
        list[i].tempy = list[i].posy;
        
        list[i].level = 6 - Math.floor(list[i].posy / gridHeight);
      }
      
      window.removeEventListener('mousemove', onMouseMove);
      window.removeEventListener('mouseup', onMouseUp);
    }
  }
  function onInputOver(e:any, index:number){
    // if(e.currentTarget != e.target){
    //   return;
    // }
    console.log('input over,', index, e.currentTarget == e.target);
    let inputs:any = inputList.value;
    for(var i=0; i<inputs.length; i++){
      if(i == index){
        inputs[i].over = true;
      }
      else{
        inputs[i].over = false;
      }
    }
  }
  function onInputOut(e:any, index:number){
    if(e.currentTarget != e.target){
      return;
    }
    console.log('input out,', index, e.currentTarget == e.target);
    let inputs:any = inputList.value;
    inputs[index].over = false;
  }
  function onInputPlay(e:any, index:number){
    onFocus(e, index);

    (audioPlay.value as any).play();
  }
  function onDLoadClick(){
    if(downLoadSelected.value){
      onInputSave(null, selectIndex);
    }
    else{
      onSaveAll();
    }
  }
  function onSaveAll(){
    var inputs = inputList.value;
    var len = inputs.length;
    var count = 0;
    for(var i=0; i<len; i++){
      var data = charVoiceDataList[i];
      if(data && data.url){
        count ++;
        onInputSave(null, i);
      }
    }
    if(count <= 0){
      ElMessage({
          message: '没有可下载的语音文件！',
          type: 'error',
      })
    }
  }
  function onInputSave(e:any, index:number){
    var data = charVoiceDataList[index];
    if(!data || !data.url){
      ElMessage({
          message: '该项没有可保存的语音文件！',
          type: 'error',
      })
      return;
    }

    // var filename = data.url.split("=")[1];
    const xhr = new XMLHttpRequest();
    xhr.open('GET', data.url, true);
    xhr.responseType = 'blob';
    xhr.onload = function () {
      if (this.status === 200) {
        const blob = this.response;
        var filename = this.responseURL.split("=")[1];
        filename = filename.replace('/root/autodl-tmp/tmp/', '');
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = filename;
        document.body.appendChild(link);
        link.click();
        window.URL.revokeObjectURL(url); // 释放URL对象
        document.body.removeChild(link);
      }
    };
    xhr.send();
  }
  function onFocus(e:any, index:number){
    selectIndex = index;

    var data = charVoiceDataList[selectIndex];
    if(data){
      selectVoiceUrl.value = data.url;
    }
    else{
      selectVoiceUrl.value = '';
    }

    var selectObj = selectDic[index];
    if(selectObj){
      selectObj1.value = selectObj.select1;
      selectObj2.value = selectObj.select2;
      selectObj3.value = selectObj.select3;
    }
    let inputs:any = inputList.value;
    for(var i=0; i<inputs.length; i++){
      if(i == index){
        inputs[i].select = true;
      }
      else{
        inputs[i].select = false;
      }
    }

    let str:string = inputs[index].value;
    selectText = str;

    checkInput(str);

    pointList.value = pointDic[index];
    charLevData = charLevDataList[index];
    initPoints(str);
    initChars(str, index);

    // if(charLevData == null){
    //   if(str){
    //     connectSocket(1, selectIndex, str, isTranslate.value);
    //   }
    //   else{
    //     initPoints(str);
    //     initChars(str, index);
    //   }
    // }
    // else{
    //   if(!str){
    //     initPoints(str);
    //     initChars(str, index);
    //   }
    //   else{
    //     str = charLevData.newstr;
    //     initPoints(str);
    //     initChars(str, index);
    //   }
    // }
  }
  function checkInput(value:string){
    if(!value){
      return;
    }
    var isEnglish = /[A-Za-z]/.test(value);
    if (isEnglish) {
      ElMessage({
          message: '注意！输入文本包含有英文！',
          type: 'warning',
      })
    }
  }
  function onInput(e:any, index:number){
    console.log(e);

    let str:string = e;
    selectText = str;
    checkInput(str);
    // initChars(str, index);
    initPoints(str);

    if(str){
      // connectSocket(1, selectIndex, str, isTranslate.value);
      // connectSocket(0, selectIndex, str, isTranslate.value);

    //  // test
    //  var arr = [];
    //  for(var i=0; i<30; i++){
    //   arr.push({'啊':{'w':1}});
    //  }
    //   var info = {translate:false, str:str, newstr:str, 'obj':arr};
    //   charLevData = info;
    //   charLevDataList[index] = info;
    //   initChars(str, index);
    }
    else{
      // initChars(str, index);
    }

    charLevDataList[index] = null;
  }
  function initChars2(str:string, index:number){
    let list:any = charLevelDic[index];//charList.value;
    var url = '';
    var curChar = '';
    var charObj;
    var valueObj;
    var pinyin;
    var value;
    var len = str.length;
    var flag = langType.value == 'JP' || isTranslate.value;
    const levelMax = flag ? 2 : 5;
    if(!list){
      list = [];
      charList.value = list;
      list = charList.value;
      charLevelDic.push(list);//charLevData
      for(var i=0; i<len; i++){
        //ref([{char:"",select:1,levels:[{bgcolor:"white"}]}]);

        // curChar = str.charAt(i);
        // charObj = charLevData.obj[i];
        // valueObj = charObj[curChar];
        // for(var key in valueObj){
        //   pinyin = key;
        //   value = valueObj[key];
        // }
        // console.log(pinyin,value);
        
        //new
        curChar = str.charAt(i);
        valueObj = charLevData.obj[i];
        for(var key in valueObj){
          pinyin = key;
          value = valueObj[key];
        }

        var arr = [];
        for(var j=0; j<levelMax; j++){
          if(levelMax < 5){
            url = baseUrl + '/assets/音叶/mobile/音调'+(j*2+2)+'.png';
          }
          else{
            url = baseUrl + '/assets/音叶/mobile/音调'+(j+1)+'.png';
          }
          if(j == (value-1)){
            arr.push({bgcolor:"lightblue",select:true,opacity:1, icon:url});
          }
          else{
            arr.push({bgcolor:"white",select:false,opacity:0.6, icon:url});
          }
        }
        list.push({char:curChar,levels:arr});
      }
    }
    else{
      charList.value = list;
      list = charList.value;
      list.length = 0;
      for( i=0; i<len; i++){
        //ref([{char:"",select:1,levels:[{bgcolor:"white"}]}]);

        // curChar = str.charAt(i);
        // charObj = charLevData.obj[i];
        // valueObj = charObj[curChar];
        // for(var key in valueObj){
        //   pinyin = key;
        //   value = valueObj[key];
        // }
        
        //new
        curChar = str.charAt(i);
        valueObj = charLevData.obj[i];
        for(var key in valueObj){
          pinyin = key;
          value = valueObj[key];
        }

        var arr = [];
        for(var j=0; j<levelMax; j++){
          if(levelMax < 5){
            url = baseUrl + '/assets/音叶/mobile/音调'+(j*2+2)+'.png';
          }
          else{
            url = baseUrl + '/assets/音叶/mobile/音调'+(j+1)+'.png';
          }
          if(j == (value-1)){
            arr.push({bgcolor:"lightblue",select:true,opacity:1, icon:url});
          }
          else{
            arr.push({bgcolor:"white",select:false,opacity:0.001, icon:url});
          }
        }
        list.push({char:curChar,levels:arr});
      }
    }
  }
  function initChars(str:string, index:number){
    if(isMobile.value){
      initChars2(str, index);
      return;
    }
    let list:any = charLevelDic[index];//charList.value;
    var url = '';
    var curChar = '';
    var charObj;
    var valueObj;
    var pinyin;
    var value;
    var len = str.length;
    var flag = langType.value == 'JP' || isTranslate.value;
    const levelMax = flag ? 2 : 5;
    if(!list){
      list = [];
      charList.value = list;
      list = charList.value;
      charLevelDic.push(list);//charLevData
      for(var i=0; i<len; i++){
        //ref([{char:"",select:1,levels:[{bgcolor:"white"}]}]);

        //old
        // curChar = str.charAt(i);
        // charObj = charLevData.obj[i];
        // valueObj = charObj[curChar];
        // for(var key in valueObj){
        //   pinyin = key;
        //   value = valueObj[key];
        // }
        // console.log(pinyin,value);

        // var info = {translate:false, str:contentStr, newstr:contentStr, 'obj':data.output.data[2]};
        //   charLevData = info;
        //new
        curChar = str.charAt(i);
        valueObj = charLevData.obj[i];
        for(var key in valueObj){
          pinyin = key;
          value = valueObj[key];
        }

        var arr = [];
        for(var j=0; j<levelMax; j++){
          if(levelMax < 5){
            url = baseUrl + '/assets/音叶/ydset'+(j*2+2)+'.png';
          }
          else{
            url = baseUrl + '/assets/音叶/ydset'+(j+1)+'.png';
          }
          if(j == (value-1)){
            arr.push({bgcolor:"lightblue",select:true,opacity:1, icon:url});
          }
          else{
            arr.push({bgcolor:"white",select:false,opacity:0.001, icon:url});
          }
        }
        list.push({char:curChar,levels:arr});
      }
    }
    else{
      charList.value = list;
      list = charList.value;
      list.length = 0;
      for( i=0; i<len; i++){
        //ref([{char:"",select:1,levels:[{bgcolor:"white"}]}]);

        // curChar = str.charAt(i);
        // charObj = charLevData.obj[i];
        // valueObj = charObj[curChar];
        // for(var key in valueObj){
        //   pinyin = key;
        //   value = valueObj[key];
        // }
        
        //new
        curChar = str.charAt(i);
        valueObj = charLevData.obj[i];
        for(var key in valueObj){
          pinyin = key;
          value = valueObj[key];
        }

        var arr = [];
        for(var j=0; j<levelMax; j++){
          if(levelMax < 5){
            url = baseUrl + '/assets/音叶/ydset'+(j*2+2)+'.png';
          }
          else{
            url = baseUrl + '/assets/音叶/ydset'+(j+1)+'.png';
          }
          if(j == (value-1)){
            arr.push({bgcolor:"lightblue",select:true,opacity:1, icon:url});
          }
          else{
            arr.push({bgcolor:"white",select:false,opacity:0.001, icon:url});
          }
        }
        list.push({char:curChar,levels:arr});
      }
    }
    
  }
  const preventDefault = (event:any) => {
    // event.preventDefault();
  };
  const handleMouseMove = (event:any) => {
    if (charTempFlag.value) {
      let div:any = document.getElementById("charEmo");
      const rect = div.getBoundingClientRect();
      const y = event.clientY - rect.top - charTempStart;

      const height = isTranslate.value ? gridHeight : gridHeight * 4;
      const num = Math.max(0, Math.min(height, (y / height) * height));
      charTempY.value = num + 'px';

      let list:any[] = charList.value;
      let levelObj:any = list[charTempIdx1];
      let levels:Array<object> = list[charTempIdx1].levels;
      charTempIdx2 = Math.round(num / gridHeight);
      console.log('charTempIdx2', charTempIdx2);
      let obj:any = levels[charTempIdx2];

      charTempIcon.value = obj.icon;
      charTempObj = obj;
    }
  };
  
  const handleMouseUp = () => {
    charTempFlag.value = false;
    var obj = charTempObj;
    if(charTempObj){
      let list:any[] = charList.value;
      let levelObj:any = list[charTempIdx1];
      let levels:Array<object> = list[charTempIdx1].levels;

        onLevelClick(null, charTempIdx1, charTempIdx2);

      for(var i=0; i<levels.length; i++){
        obj = levels[i];
        if(i == charTempIdx2){
          obj.opacity = 1;
          obj.bgcolor = "lightblue";
          obj.select = true;
        }
        else{
          obj.opacity = 0.001;
          obj.bgcolor = "white";
          obj.select = false;
        }
      }
      charTempObj = null;
      
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    }
  };
  
  function yydcTouchEnd(event:any, index1:number, index2:number){
    if(isCharTouchMove){
      isCharTouchMove = false;
      return;
    }
    let list:any[] = pointList.value;
    let obj:any = list[index1];
    obj.level = index2;
    var icons = obj.icons;
    var len = icons.length;
    for(var i=0; i<len; i++){
      if(index2 == i){
        icons[i].selected = true;
      }
      else{
        icons[i].selected = false;
      }
    }
    pointList.value = list;
  };
  const handleMouseDown = (event:any, index1:number, index2:number) => {
    charTempFlag.value = true;

    let list:any[] = charList.value;
    let levelObj:any = list[index1];
    let levels:Array<object> = list[index1].levels;
    let obj:any = levels[index2];
    charTempIcon.value = obj.icon;
    charTempIdx1 = index1;
    charTempIdx2 = index2;
    // charTempObj = obj;
    
    obj.opacity = 0.001;
    obj.bgcolor = "white";
    obj.select = false;

    let div2:any = document.getElementById('charEmo');
    // let div2:any = imgpoint.value;
    const rect2 = div2.getBoundingClientRect();
    charTempX.value = (index1 * gridWidth + 12) + 'px';
    charTempStart = event.clientY - (rect2.top + (gridHeight * index2) - 0);

    console.log("rect2.top=", rect2.top);
    handleMouseMove(event);
  
    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
  };
  function onLevelClick(e:any, index1:number, index2:number){
    let list:any[] = charList.value;
    let levelObj:any = list[index1];
    let levels:Array<object> = list[index1].levels;
    let obj:any;

    var levelData = charLevDataList[selectIndex];
    let pinyin:any;
    var value;
    if(levelData){
      // var curChar = levelObj.char;
      // var charObj = levelData.obj[index1];
      // var valueObj = charObj[curChar];
      // for(var key in valueObj){
      //   pinyin = key;
      //   value = valueObj[key];
      // }
      var valueObj = levelData.obj[index1];
      for(var key in valueObj){
        pinyin = key;
        value = valueObj[key];
      }
    }
    else{
      return;
    }

    for(var i=0; i<levels.length; i++){
      obj = levels[i];
      if(i == index2){
        obj.bgcolor = "lightblue";
        obj.opacity = 1;
        obj.select = true;
        if(pinyin){
          valueObj[pinyin] = i + 1;
        }
      }
      else{
        obj.bgcolor = "white";
        obj.select = false;
        obj.opacity = 0.001;
      }
    }

    //保存
    charLevelDic[selectIndex] = list.concat();
  }
  const add = (e:any, params:any) => {
    console.log(e, params);
    let arr:any  = inputList.value;
    arr.push({value:""});

    selectDic.push({select1:'中文', select2:'adachi', select3:'Neutral'});
    
    let list:any = ref([]);
    pointDic.push(list.value);

    refreshInputHeight();
  }
  function isJP(){
    var flag = langType.value == 'JP' || isTranslate.value;
    return flag;
  }
  function refreshInputHeight(){
    let len:number = inputList.value.length;
    var h1:number = isMobile ? 103 : 91;
    var h2:number = isMobile ? 125 : 112;
    var height:number = len * h1 + 3;
    if(isTranslate.value){
      height = len * h2 + 3;
    }
    if(!isMobile){
      if(showSet.value){
        var minH = INPUT_MIN_H;
        if(isTranslate.value){
          minH = INPUT_MIN_H + 50;
        }
        if(height > minH){
          height = minH;
        }
      }
      else{
        if(height > 760){
          height = 760;
        }
      }
    }
    else{
      if(height > 355){
        height = 355;
      }
    }
    inputHeight.value = height;
  }
  const onDelete = (e:any, index:any) => {
    console.log(e, index);
    let arr:any = inputList.value;
    if(arr.length <= 1){
      ElMessage("必须保留一个");
      return;
    }
    for(var i=0; i<arr.length; i++){
      if(i == index){
        arr.splice(i, 1);
        pointDic.splice(i, 1);
        charLevelDic.splice(i, 1);
        selectDic.splice(i, 1);

        onFocus(null, 0);
        (inputScroll.value as any).setScrollTop(0);
        break;
      }
    }
    refreshInputHeight();
  }

  //输入框
  // for(var i=0; i<inputList.length; i++){
  //   inputList[i].value = "";
  // }
  //滑块
  const sliderList = ref([
    {name: '强度', value: 1, temp:1, min:0, max:20}
    // {name: 'top_p', value: 0, min:0, max:1},
    // {name: 'temperature', value: 0, min:0, max:1}
  ])
  //下拉菜单
  const options1 = [
  {
    value: 'ZH',
    label: '中文',
  },
  {
    value: 'JP',
    label: '日文',
  }
]
  //配音员
  const voiceTypes = ["adachi","chitose","jiuer","kasuga","kekewei","kiryu","liuzhaokun","liuzhixiao","nuochen","senzhongren","shuiyuan","wensen","wudaniang","xiantawutong","xiaoN","xuewei","yueyeqiao","zhuquecheng","zuoyeyangguang"]
  let options2:any[] = [];
  var len = voiceTypes.length;
  for(var i=0; i<len; i++){
    options2.push({value:voiceTypes[i], label:voiceTypes[i]});
  }
  //情绪
  const emoTypes = ["Neutral","默认","低落","冷漠","哭泣","喜悦","大叫","大笑","嫌弃","害怕","尴尬","忍痛","悄悄话","悲伤","温柔","激动","生气","疑惑","着急","诧异","责怪","高兴"];
  let options3:any[] = [];
  var len = emoTypes.length;
  for(var i=0; i<len; i++){
    options3.push({value:emoTypes[i], label:emoTypes[i]});
  }


  const options = [
  {
    value: 'Option1',
    label: 'Option1',
  },
  {
    value: 'Option2',
    label: 'Option2',
  },
  {
    value: 'Option3',
    label: 'Option3',
  },
  {
    value: 'Option4',
    label: 'Option4',
  },
  {
    value: 'Option5',
    label: 'Option5',
  },
]

const fnIndexDic:any = {};


//HttpSend
class HttpSend {
  // 属性
  data: any;
  fn_index: number;
  session_hash: string;
  trigger_id:number;
  httpUrl:string;
  inputIndex:number;
  contentStr:string;
 
  // 构造函数
  constructor(data:any, fn_index:number, session_hash:string, trigger_id:number, contentStr:string='',inputIndex:number=0) {
    this.data = data;
    this.fn_index = fn_index;
    this.session_hash = session_hash;
    this.trigger_id = trigger_id;
    this.contentStr = contentStr;
    this.inputIndex = inputIndex;

    // this.httpUrl = 'http://192.168.2.100:7860/queue';
    this.httpUrl = 'http://8919j8p607.vicp.fun/queue';
  }

  
  start(){
    this.joinSend();
  }
  async joinSend(){

    var payload:any = {
      "data":this.data,
      "event_data": null,
      "fn_index":this.fn_index,
      "session_hash":this.session_hash,
      "trigger_id":this.trigger_id
    };

    var heads:any = {'Content-Type': "application/json"};

    const resp = await fetch(this.httpUrl + '/join?', {
      method: "POST",
      body:JSON.stringify(payload),
      headers: { ...heads},
      credentials: "include"
    });
    console.log('http1111111--->',resp);
   
    this.dataSend();
  }
  async dataSend(){
    const resp = await fetch(this.httpUrl + '/data?session_hash=' + this.session_hash, {
      method: "GET",
      credentials: "include"
    });
    if(resp.status == 200){
      // resp.json().then(res => {
      //   console.log('http2222222--->', res);
      // })

      
      const inputIndex:number = this.inputIndex;
      const contentStr:string = this.contentStr;

      resp.text().then(res => {
        console.log('解析出文本：--->', res);

        var index = res.lastIndexOf("success");
        var start = res.lastIndexOf('data: {', index);
        var str = res.substring(start+6, index + '"success":true}'.length);
        console.log('sdlfjds====>', str);
        var data = JSON.parse(str);
        
        console.log('结构体====>', data);

        if(this.fn_index == 0){
          //必需品语音数据
          var tmpstr:string = data.output.data[2];
          tmpstr = tmpstr.replace(/'/g, '"');
          var tmpobj = JSON.parse(tmpstr);
          var info = {translate:false, str:contentStr, newstr:contentStr, 'obj':tmpobj};
          charLevData = info;
          charLevDataList[inputIndex] = info;

          //保存语音。
          var url = data.output.data[1].url;
          let data2:any = {url:url, duration: data.output.duration};
          selectVoiceUrl.value = url;
          charVoiceData = data2;
          charVoiceDataList[inputIndex] = data2;

          generateCount ++;
          generateStr.value = "语音生成中（"+generateCount+"/"+generateNum+"）。。。";
          if(generateCount >= generateNum){
            
            initPoints(contentStr);
            initChars(contentStr, inputIndex);

            setTimeout( ()=>{
              isGenerating.value = false;
              if(generateError){
                clearTimeout(generateError);
                generateError = 0;
              }
            }, 500);
          }
          else{
            makeSingle(generateArr[generateCount]);
          }
          
        }
      })

      // // 转换流为文本
      // var stream:any = resp.body;
      // const reader = stream.getReader();
      // reader.read().then(({ value, done }) => {
      //   if (done) {
      //     return '';
      //   }
      //   // 使用TextDecoder转换Uint8Array为字符串
      //   const decoder = new TextDecoder('utf-8');
      //   var text = decoder.decode(value);
      //   console.log('解析出文本：',text);
      // });
    }
    
  }
}
//websocket
class SocketSend {
  // 属性
  fnIndex: number;
  inputIndex: number;
  content: any;
  translate:boolean;
 
  // 构造函数
  constructor(fnIndex: number, inputIndex:number, content: any, translate:boolean) {
    this.fnIndex = fnIndex;
    this.inputIndex = inputIndex;
    this.content = content;
    // this.translate = false;//translate;//临时屏蔽，为了测试
    this.translate = translate;//临时屏蔽，为了测试
  }
 
  // 方法
  start() {
    console.log(this.fnIndex,"--==-->");

    let fnIndex:number = this.fnIndex;
    let inputIndex:number = this.inputIndex;
    let content: any = this.content;
    let translate: any = this.translate;

    if(fnIndex == 3){
      isGenerating.value = true;
    }
    // const socket = new WebSocket('wss://u88368-8642-f9ec22e0.westb.seetacloud.com:8443/queue/join');
    const socket = new WebSocket('wss://u88368-b98c-de32db34.yza1.seetacloud.com:8443/queue/join');
    

    // 监听连接建立事件
    socket.addEventListener('open', (event) => {
      console.log('WebSocket连接已建立');
    });

    // 监听消息接收事件
    socket.addEventListener('message', (event) => {
      console.log('收到消息：', event.data);
      var obj = JSON.parse(event.data);
      if(obj.msg == 'send_hash'){
        send('{"fn_index":'+fnIndex+',"session_hash":\"'+session_hash+'\"}');
      }
      else if(obj.msg == 'send_data'){
        if(fnIndex == 1 || fnIndex == 0){
          var data = {
            "data": [
              content,
              "zh",
              translate
            ],
            "event_data": null,
            "fn_index": fnIndex,
            "session_hash": session_hash
          }
          send(JSON.stringify(data));
        }
        else if(fnIndex == 3){
          send(JSON.stringify(content));
        }
      }
      else if(obj.msg == 'process_completed'){
        let info:any;
        console.log(this.fnIndex,"+++++++>");
        if(fnIndex == 0){//抑扬顿挫
          socket.close();
          let infostr:string = obj.output.data[0];
          try{
            info = JSON.parse(infostr);
            
            var list = pointList.value;
            for(var i=0; i<list.length; i++){
              list[i].level = info[i];
            }

            var obj3 = charLevDataList[inputIndex];
            if(obj3){
              initPoints(obj3.newstr, info);
            }
            else{
              initPoints(content, info);
            }
          }
          catch(e:any){
            ElMessage({
                message: '返回信息json解析报错！fnIndex=0,'+infostr,
                type: 'error',
            })
            console.error("0返回信息json解析报错！",infostr);
          }
        }
        else if(fnIndex == 1){//音调
          socket.close();
          let infostr:string = obj.output.data[1];
          if(translate){//翻译成日语

            let inputs:any = inputList.value;
            var japInput:any = inputs[inputIndex];
            japInput.japStr = obj.output.data[0];

            info = {translate:true, str:infostr};
            charLevData = info;
            charLevDataList[inputIndex] = info;
            initPoints(infostr);
            initChars(infostr, inputIndex);
          }
          else{//中文
            var newstr = '';
            try{
              var iobj = JSON.parse(infostr);

              // let pinyin:any;
              // var value;
              // var arr = iobj;
              // for(var i=0; i<arr.length; i++){
              //   for(var key in arr[i]){
              //     newstr += key;
              //   }
              // }
              newstr = obj.output.data[0];

              info = {translate:false, str:content, newstr:newstr, 'obj':iobj};
              charLevData = info;
              charLevDataList[inputIndex] = info;
            }
            catch(e:any){
              ElMessage({
                  message: '返回信息json解析报错！fnIndex=1,'+infostr,
                  type: 'error',
              })
              console.error("1返回信息json解析报错！-->"+infostr+"<--");
            }
            if(inputIndex == selectIndex){
              if(newstr.length != content.length){
                ElMessage({
                    message: '注意！返回的文本与输入内容不一致，请检查是否包含了非法字符。',
                    type: 'error',
                })
              }
              initPoints(newstr);
              initChars(newstr, inputIndex);
            }
          }
        }
        else if(fnIndex == 3){//生成的语音文件返回
          info = obj.output.data;
          var url = 'https://u88368-b98c-de32db34.yza1.seetacloud.com:8443/file=' + info[0].name;
          let data:any = {url:url, duration: info.duration};
          selectVoiceUrl.value = url;
          charVoiceData = data;
          charVoiceDataList[inputIndex] = data;

          generateCount ++;
          generateStr.value = "语音生成中（"+generateCount+"/"+generateNum+"）。。。";
          if(generateCount >= generateNum){
            setTimeout( ()=>{
              isGenerating.value = false;
              if(generateError){
                clearTimeout(generateError);
                generateError = 0;
              }
            }, 500);
          }
          else{
            makeSingle(generateArr[generateCount]);
          }
        }
      }
    });

    // 监听连接关闭事件
    socket.addEventListener('close', (event) => {
      console.log('WebSocket连接已关闭');
    });

    const send = (str:any)=> {
      // 发送消息给服务器
      socket.send(str);
    }
  }
}
// function connectSocket(fnIndex:number, inputIndex:number, content:any, translate:boolean)
function connectSocket(fnIndex:number, inputIndex:number, data:any, contentStr:string, translate:boolean)
{
  // var mysocket = new SocketSend(fnIndex, inputIndex, content, translate);
  // mysocket.start();

  // var data:any = ["model_zh", modelUrl.value];
  
  isGenerating.value = true;
  var http = new HttpSend(data, fnIndex, session_hash, 22, contentStr, inputIndex);
  http.start();
}
function httpLogin(){
  var data:any = ["model_zh", modelUrl.value];
  var http = new HttpSend(data, 4, session_hash, 13);
  http.start();
}
  
</script>

<style scoped>

/*
移动端css
*/
html {
    font-size: 36px; /* 或者使用10px，取决于你的设计需求 */
}
.scroll-container {
  height: 300px; /* 设置一个固定高度 */
  overflow-y: scroll; /* 开启垂直滚动条 */
  -webkit-overflow-scrolling: touch; /* 对移动端友好的滚动 */
}
.scroll-content {
  height: 600px; /* 设置一个比容器高的高度以便产生滚动 */
  width:100%;
  background-color: aquamarine;
}
.m-mobile{
  position:relative;
  width: 100%;
  height: 100%;
}
.m-content{
  position:relative;
  width: 100%;
  background-color: #2e2e2e;
  margin-top: 10px;
  border: 1px solid #d8d8d8;
  border-radius: 10px;
}
.m-div-ctn{
  position:relative;
  margin-top:0px;
  margin-left: 3%;
  width: 94%;
  height:844px;
  background-color: #2e2e2e;
}
.m-btn-voice :deep(.el-radio-button__inner) {
  background:#d8d8d8;
}
.m-btn-voice :deep(.el-radio-button__original-radio:checked+.el-radio-button__inner) {
  color:black;
  background-color:#f2ffd3;
}
.m-left {
  left:0px;
  width:100%;
  height:100%;
  box-sizing: border-box;
}
.m-right {
  right:0px;
  width:27%;
  height:100%;
  box-sizing: border-box;
  border-left: 1px solid #8b8b8b;
  text-align: center;
}


/*
PC端、平板端css
*/
.custom-select-color :deep(.el-popper__arrow:before) {
  background: #737373; /* 下拉框上面的三角箭头颜色 */
}
.custom-select-color :deep(.el-select__wrapper) {
  background-color: #737373 !important;
  box-shadow: none;
  height: 34px;
}
.custom-select-color :deep(.el-select__placeholder) {
  color: white;
}
.custom-select-color :deep(.el-select__icon) {
  /* 输入框右侧的箭头 */
  color: white;
  font-size: 20px;
  font-weight: bold;
}
.m-custom-select-color2 :deep(.el-select-dropdown__wrap) {
  max-height: 660px !important;
}
.m-custom-select-color2 :deep(.el-select-dropdown) {
  background-color: #737373; /* 设置下拉菜单背景色 */
  color: aquamarine;
  height: 660px;
}
.m-custom-select-color3 :deep(.el-select-dropdown__wrap) {
  max-height: 760px !important;
}
.m-custom-select-color3 :deep(.el-select-dropdown) {
  background-color: #737373; /* 设置下拉菜单背景色 */
  color: aquamarine;
  height: 760px;
}
.custom-select-color :deep(.el-select-dropdown) {
  background-color: #737373; /* 设置下拉菜单背景色 */
  color: aquamarine;
}
.custom-select-color :deep(.el-select-dropdown__item) {
  color: rgb(197, 196, 196);
}
.custom-select-color :deep(.el-select-dropdown__item.is-hovering) {
  background-color: #585858 !important; /* 设置下拉菜单项hover和selected背景色 */
  color: white;
}
.custom-select-color :deep(.el-select-dropdown__item.is-selected) {
  background-color: #3b3b3b !important; /* 设置下拉菜单项hover和selected背景色 */
  color: white;
}

:root {
  --full-width: 100%; /* 定义100%的变量 */
}
.make-div{
  width: 252px;
  height: 82px;
  position:absolute;
  top: 20px;
  left: calc((100% - 516px - 252px) / 2 - 126px + 458px);
}
.make-div2{
  width: 252px;
  height: 82px;
  position:absolute;
  top: 20px;
  right: 58px;
}
.make-btn{
  position:relative;
  width: 116px;
  height: 44.33px;
  margin-left: 68px;
  cursor:pointer;
}
.make-cur{
  position:relative;
  width: 20px;
  height: 21.5px;
  cursor:pointer;
}
.make-all{
  position:relative;
  width: 244px;
  height: 57px;
  cursor:pointer;
}
.bottom-div{
  position: relative;
  width: 100%;
}
.save-all{
  position: absolute; top: 0px; left: 460px;height: 106px;width: 180px;font-size: 22px;
}
.audio{
  position: relative;
  width: 400px !important;
  height: 106px !important;
  margin-left: 58px;
  margin-top: 20px;
}
.m-audio{
  position: relative;
  width: 100% !important;
  height: 175px !important;
  margin-left: 0px;
  margin-top: 0px;
}
.icon-yydc{
  width: 26px;
  height: 27px;
  margin-top: 10px;
  margin-left: 20px;
}
.icon-yydc2{
  position:absolute;
  width: 26px;
  height: 27px;
  top: 0px;
  left: 12px;
}
.btn-add{
  width: 156px;
  height:51.33px;
  margin-left:58px;
  margin-top: 6px;
}
.item-icon{
  width: 16px;
  height: 16px;
  margin-left: 13px;
}
.body{
  position:absolute;
  width: 100%;
  height: 100%;
  background-color: #222429;
}
.el-select {
  border-color: #999; /* 边框颜色 */
}
 
.el-input__inner {
  color: #333; /* 文本颜色 */
}

.borderless :deep(.el-input__wrapper) {
    box-shadow: 0 0 0 0px var(--el-input-border-color, var(--el-border-color)) inset;
    background:#F8F8F8;
    cursor: default;
    .el-input__inner {
        cursor: default !important;
    }
}
.borderless :deep(.el-textarea__inner) {
    outline: none;
    border: none !important;
    resize: none;
    box-shadow: none;
    background:#F8F8F8;
    font-size: 16px;
    letter-spacing: 2px;
}
.borderless2 :deep(.el-input__wrapper) {
    box-shadow: 0 0 0 0px var(--el-input-border-color, var(--el-border-color)) inset;
    background:#2e2e2e;
    cursor: default;
    .el-input__inner {
        cursor: default !important;
    }
}
.borderless2 :deep(.el-textarea__inner) {
    outline: none;
    border: none !important;
    resize: none;
    box-shadow: none;
    background:#2e2e2e;
    font-size: 1.2rem;
    letter-spacing: 2px;
}
.myprogress{
  position:relative;
  width: calc(100% - 82px);
  height: 50px;
}
.m-myprogress{
  position:relative;
  width: calc(98% - 0px);
  height: 50px;
  margin-top: 10px;
}
.jap-ctn{
  position: absolute;
  width: 100%;
  top: 50px;
  left: 0px;
}
.jap-line{
  width: 85%;
  margin-left: 10px;
  border: 1px solid #696969;
}
.input-ctn{
  position: relative;
  width: 100%;
  height: 86px;
  margin-top: 12px;
  box-sizing: border-box;
}
.input-ctn2{
  position: absolute;
  width: calc(100% - 100px);;
  height: 74px;
  border: 2px solid #8b8b8b;
  border-radius: 10px;
  left: 38px;
}
.input-tag{
  position:absolute;
  width: 62px;
  height: 25px;
  top: -12px;
  left: 14px;
  background-color: #2e2e2e;
  color: white;
  font-weight: bold;
  letter-spacing: 5px;
  text-align: center;
  font-size: 1rem;
  font-family: '黑体'; /* 这里设置你想要的默认字体 */
}
.m-input-tag{
  font-size: 1.5rem;
  width: 100px;
  font-weight: normal;
}
.div-ctn{
  position:absolute;
  top:0px;
  left: 0px;
  width: 100%;
  height:1080px;
  background-color: #2e2e2e;
}
.mask-ctn{
  position:absolute;
  top:0px;
  left: 0px;
  width: 100%;
  height:1080px;
  text-align: center;
}
.m-mask-ctn{
  position:absolute;
  top:0px;
  left: 0px;
  width: 100%;
  height:100%;
  text-align: center;
}
.mask{
  position:absolute;
  top:0px;
  left: 0px;
  width: 100%;
  height:100%;
  background-color: black;
  opacity: 0.72;
}
.mask-txt{
  position: relative;
  font-size: 30px;
  margin-top: 400px;
  top: 400px;
  color: rgb(255, 5, 5);
}
.m-mask-txt{
  position: relative;
  font-size: 30px;
  margin-top: 400px;
  top: 35%;
  color: rgb(255, 5, 5);
}
.output-ctn{
  width: 100%;
  height: 100%;
  text-align: center;
  margin-top: 20px;
}
.audio{
  width: 80%;
}
.scrollbar2{
  width: calc(100% - 70px);
  height: 200px;
  margin-top: 6px;
  margin-left: 20px;
}
.set-ctn2{
  position: relative;
  width: calc(100% - 116px);
  height: 36px;
  border: 1px solid #8b8b8b;
  margin-top: 5px;
  margin-left: 58px;
  border-radius: 10px;
}
.set-text{
  font-size: 17px;
  color: white;
  height: 1.5em;
  font-weight: bold;
  letter-spacing:4px;
}
.set-text2{
  font-size: 1.4rem;
  color: white;
  font-weight: normal;
  letter-spacing:4px;
}
.set-text-normal{
  font-size: 1.4rem;
  color: white;
  font-weight: normal;
  width: 100%;
}
.set-text3{
  font-size: 17px;
  color: white;
  height: 1.5em;
  font-weight: bold;
  letter-spacing:2px;
}
.set-ctn{
  position: relative;
  width: calc(100% - 116px);
  height: 570px;
  border: 1px solid #8b8b8b;
  margin-top: 6px;
  margin-left: 58px;
  border-radius: 10px;
}
.scrollbar{
  position:absolute;
  width: calc(100% - 64px);
  height: 531px;
  left: 32px;
  top: 22px;
}
.m-scrollbar{
  position:absolute;
  width: calc(100% - 0px);
  height: 531px;
  left: 0px;
  top: 0px;
  border: 1px solid blue;
}

.scrollbar .el-scrollbar__bar.is-vertical {
  display: none;
}
.char-ctn{
  position: relative;
  display: flex;
  margin-left: 64px;
}
.m-char-ctn{
  position: relative;
  display: flex;
  margin-left: 0px;
  margin-top: 5px;
}
.char-temp{
  position:absolute;
  width: 26px;
  height: 27px;
}
.char{
  width: 51px;
  height: 51px;
  box-sizing: border-box;
  text-align: center;
  flex-shrink: 0;
  color: white;
  font-size: 30px;
}
.char-gd{
  position: relative;
  height: 37px;
  user-select: none;
  border: none;
  background-color: rgba(0, 0, 0, 0.02);
}

.m-char{
  width: 68px;
  height: 68px;
  box-sizing: border-box;
  text-align: center;
  flex-shrink: 0;
  color: white;
  font-size: 30px;
  /**border: 1px solid orange;**/
}
.cbox{
  position:absolute;
}
.yydc{
  position: relative;
  width: calc(100% - 64px);
  height: 242px;
  border-top: 1px solid #8b8b8b;
  border-left: 1px solid #666666;
  border-right: 1px solid #666666;
  border-bottom: 1px solid #3a3939;
  background-color: #282828;
  border-radius: 6px;
  margin-left: 32px;
  margin-top:3px;
  box-shadow:2px 5px 8px 0px rgba(0,0,0, 0.4);
}
.point-ctn {
  position:absolute;
  width:100%;
  height:220px;
  box-sizing: border-box;
  /**border: 1px solid rgb(115, 85, 223);**/
  display: flex;
  flex-direction: row;
  left: 60px;
  top:27px;
}
.point{
  position:absolute;
  
  width: 26px; /* 设置你想要显示的宽度 */
  height: 28px; /* 设置你想要显示的高度 */
  background-position: 'top'; /* 设置背景图片的起始位置 */
  background-size: 100%; /* 设置背景图片的大小，这里是比容器大小多出一倍 */
  background-image: url('./assets/音叶/旋钮-抑扬顿挫.png');
}
.slider{
  margin-left:5%;
  width:95%;
}
.test {
  position: relative;
  width:100%;
  /**border: 1px solid rgb(115, 85, 223);**/
  margin-top:15px;
  display: flex;
  flex-direction: column;
}
.m-test {
  position: relative;
  width:98%;
  /**border: 1px solid rgb(115, 85, 223);**/
  margin-top:15px;
  display: flex;
  flex-direction: column;
}
.project {
  width:100%;
  height:60px;
  background-color: #202020;
}
.left {
  position: absolute;
  left:0px;
  width:73%;
  height:100%;
  box-sizing: border-box;
}
.right {
  position: absolute;
  right:0px;
  width:27%;
  height:100%;
  box-sizing: border-box;
  border-left: 1px solid #8b8b8b;
  text-align: center;
}
.right2{
  position: absolute;
  width: 92%;
  left: 4%;
}
.translate{
  position: absolute;
  width: 90px;
  right:0px;
  top: 15px;
  color: white;
}
.translate-btn{
  width: 39px;
  height:18px;
  margin-left:0px;
  margin-top: 0px;
}
.m-translate-btn{
  width: 70px;
  height:32px;
  margin-left:0px;
  margin-top: 0px;
}
.scroll-right{
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>